package com.tqz.rc.server.core;

import com.tqz.rc.common.util.EnvUtil;
import com.tqz.rc.server.cluster.MemberUtils;
import com.tqz.rc.server.cluster.ServiceMemberManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestComponent;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>一致性协议操作类
 *
 * @author tianqingzhao
 * @since 2021/9/24 9:44
 */
@Component
public class DistroMapper {

    private volatile List<String> healthyList = new ArrayList<>();

    @Autowired
    private ServiceMemberManager memberManager;

    @PostConstruct
    public void init() {
        this.healthyList = MemberUtils.simpleMembers(memberManager.allMembers());
    }

    /**
     * 根据服务名称hash取模
     *
     * @param serviceName 服务名称
     * @return
     */
    public boolean responsible(String serviceName) {
        final List<String> servers = healthyList;

        if (CollectionUtils.isEmpty(servers)) {
            // means distro config is not ready yet
            return false;
        }

        int index = servers.indexOf(EnvUtil.getLocalAddress());
        int lastIndex = servers.lastIndexOf(EnvUtil.getLocalAddress());
        if (lastIndex < 0 || index < 0) {
            return true;
        }

        int target = distroHash(serviceName) % servers.size();
        return target >= index && target <= lastIndex;
    }

    private int distroHash(String responsibleTag) {
        return Math.abs(responsibleTag.hashCode() % Integer.MAX_VALUE);
    }
}
